<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>http缓存 | 罗锦安的blog</title>
    <meta name="description" content="vue、js、nodejs等等的学习记录">
    <link rel="stylesheet" href="/giteepage_blog/assets/style.7751b5f0.css">
    <link rel="modulepreload" href="/giteepage_blog/assets/app.8c2b9bab.js">
    <link rel="modulepreload" href="/giteepage_blog/assets/http_http缓存.md.9d2bfdf4.lean.js">
    
    <script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
  </head>
  <body>
    <div id="app"><div class="Layout" data-v-fc91a531><!--[--><!--]--><!--[--><span tabindex="-1" data-v-19a00f3c></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-19a00f3c> Skip to content </a><!--]--><!----><header class="VPNav" data-v-fc91a531 data-v-2e5b0dfc><div class="VPNavBar has-sidebar" data-v-2e5b0dfc data-v-57336f2d><div class="container" data-v-57336f2d><div class="VPNavBarTitle has-sidebar" data-v-57336f2d data-v-60d74ef4><a class="title" href="/giteepage_blog/" data-v-60d74ef4><!--[--><!--]--><!----><!--[-->罗锦安的blog<!--]--><!--[--><!--]--></a></div><div class="content" data-v-57336f2d><!--[--><!--]--><!----><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-57336f2d data-v-ddeb1f26><span id="main-nav-aria-label" class="visually-hidden" data-v-ddeb1f26>Main Navigation</span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="https://gitee.com/luojinan1" target="_blank" rel="noreferrer" data-v-ddeb1f26 data-v-230f9108 data-v-bf6d4382><!--[-->gitee<!--]--><!----></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-57336f2d data-v-ae9a97bb><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-ae9a97bb data-v-9312fe85 data-v-a71afa9e><span class="check" data-v-a71afa9e><span class="icon" data-v-a71afa9e><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-9312fe85><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-9312fe85><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-57336f2d data-v-446c2ad9 data-v-2c4090e8><!--[--><a class="VPSocialLink" href="https://gitee.com/luojinan1" target="_blank" rel="noopener" data-v-2c4090e8 data-v-a99e5443><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-57336f2d data-v-f14df81d data-v-97fd8b98><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-97fd8b98><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-97fd8b98><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-97fd8b98><div class="VPMenu" data-v-97fd8b98 data-v-79123c45><!----><!--[--><!--[--><!----><div class="group" data-v-f14df81d><div class="item appearance" data-v-f14df81d><p class="label" data-v-f14df81d>Appearance</p><div class="appearance-action" data-v-f14df81d><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" aria-label="toggle dark mode" aria-checked="false" data-v-f14df81d data-v-9312fe85 data-v-a71afa9e><span class="check" data-v-a71afa9e><span class="icon" data-v-a71afa9e><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-9312fe85><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-9312fe85><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><div class="group" data-v-f14df81d><div class="item social-links" data-v-f14df81d><div class="VPSocialLinks social-links-list" data-v-f14df81d data-v-2c4090e8><!--[--><a class="VPSocialLink" href="https://gitee.com/luojinan1" target="_blank" rel="noopener" data-v-2c4090e8 data-v-a99e5443><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-57336f2d data-v-b5a83624><span class="container" data-v-b5a83624><span class="top" data-v-b5a83624></span><span class="middle" data-v-b5a83624></span><span class="bottom" data-v-b5a83624></span></span></button></div></div></div><!----></header><div class="VPLocalNav" data-v-fc91a531 data-v-29725483><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-29725483><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-29725483><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-29725483>Menu</span></button><a class="top-link" href="#" data-v-29725483> Return to top </a></div><aside class="VPSidebar" data-v-fc91a531 data-v-4d03be81><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-4d03be81><span class="visually-hidden" id="sidebar-aria-label" data-v-4d03be81> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-4d03be81><section class="VPSidebarGroup" data-v-4d03be81 data-v-d37d8138><div class="title" data-v-d37d8138><h2 class="title-text" data-v-d37d8138> 介绍</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>介绍</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>http</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/http/http2.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>http2</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/http/http3.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>http3</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link active" href="/giteepage_blog/http/http%E7%BC%93%E5%AD%98.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>http缓存</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>innermanage</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/innermanage/%E5%86%85%E7%AE%A1%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>内管前端工程</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>interview</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/JS%E5%9F%BA%E7%A1%80.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>JS基础</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/TODO.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>TODO</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-0.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-0</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-JS%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-JS数据类型</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-this.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-this</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-事件机制</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E5%89%8D%E7%AB%AF%E7%9B%91%E6%8E%A7.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-前端监控</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E5%8E%9F%E5%9E%8B.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-原型</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E5%8F%98%E9%87%8F%E6%8F%90%E5%8D%87.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-变量提升</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E5%AE%89%E5%85%A8.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-安全</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E6%80%9D%E8%80%83%E9%A2%98.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-思考题</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E6%95%B0%E5%AD%97%E7%B2%BE%E5%BA%A6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-数字精度</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8E%9F%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-浏览器原理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E7%BB%A7%E6%89%BF.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-继承</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E7%BC%93%E5%AD%98.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-缓存</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E8%B7%A8%E5%9F%9F.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-跨域</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E4%B9%8B%E9%81%93-%E9%97%AD%E5%8C%85.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端面试之道-闭包</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E5%90%84%E7%A7%8D%E9%A2%98%E7%9B%AE01.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>各种题目01</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-callbind.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-callbind</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-instanceof.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-instanceof</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-LRU%E7%BC%93%E5%AD%98%E7%AE%97%E6%B3%95.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-LRU缓存算法</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-map%E5%92%8Cfilter%E5%92%8Creduce.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-map和filter和reduce</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-new%E5%8E%9F%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-new原理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-setTime%E6%A8%A1%E6%8B%9FsetInterval.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-setTime模拟setInterval</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E5%92%8C%E8%A7%82%E5%AF%9F%E8%80%85.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-发布订阅和观察者</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E5%A4%8D%E6%9D%82axios.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-复杂axios</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E5%A4%8D%E6%9D%82promise.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-复杂promise</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E6%95%B0%E7%BB%84%E8%BD%AC%E6%A0%91.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-数组转树</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E6%B7%B1%E6%8B%B7%E8%B4%9D.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-深拷贝</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E6%89%8B%E5%86%99%E7%B3%BB%E5%88%97-%E9%98%B2%E6%8A%96%E8%8A%82%E6%B5%81.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>手写系列-防抖节流</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-CSS.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-CSS</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-JS.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-JS</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-vue.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-vue</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-数据结构</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-%E6%9E%B6%E6%9E%84.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-架构</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/interview/%E9%9D%A2%E8%AF%95-%E7%AE%97%E6%B3%95.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>面试-算法</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>jiagou</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/monorepo.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>monorepo</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E4%BB%8E0%E5%88%B01%E6%9E%84%E5%BB%BA%E7%AC%A6%E5%90%88%E6%A0%87%E5%87%86%E7%9A%84%E5%85%AC%E5%85%B1%E5%BA%93.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>从0到1构建符合标准的公共库</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E5%88%87%E6%8D%A2%E4%B8%BB%E9%A2%98%E6%96%B9%E6%A1%88.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>切换主题方案</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E5%89%8D%E7%AB%AF%E5%9F%BA%E7%A1%80%E5%BB%BA%E8%AE%BE%E4%B8%8E%E6%9E%B6%E6%9E%8430%E8%AE%B2.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端基础建设与架构30讲</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>异步组件设计</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E6%8F%92%E4%BB%B6%E5%BC%8F%E8%AE%BE%E8%AE%A1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>插件式设计</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E6%90%AD%E5%BB%BA%E7%BB%84%E4%BB%B6%E5%BA%93.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>搭建组件库</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E6%B7%B1%E5%85%A5babel.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>深入babel</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%93%8D%E5%BA%94%E5%BC%8F%E5%BC%80%E5%8F%91%E5%8D%95%E4%BD%8D%E8%AE%BE%E8%AE%A1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>移动端响应式开发单位设计</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E6%8C%89%E9%9C%80%E5%AF%BC%E5%87%BA%E7%9B%AE%E5%BD%95.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>自动生成按需导出目录</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/jiagou/%E8%A1%A8%E5%8D%95%E7%BB%84%E4%BB%B6%E5%B8%A6%E6%A0%A1%E9%AA%8C%E5%8A%9F%E8%83%BD.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>表单组件带校验功能</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>js</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/dayFormat%E6%AD%A3%E5%88%99%E7%9A%84%E4%BD%BF%E7%94%A8.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>dayFormat正则的使用</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/ES2020.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>ES2020</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/luhn%E7%AE%97%E6%B3%95.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>luhn算法</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/Object.entries.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>Object.entries</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/proxy.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>proxy</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/serviceWorker.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>serviceWorker</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E4%BC%98%E9%9B%85%E7%9A%84Class.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>优雅的Class</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E4%BD%A0%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84js-%E5%BC%82%E6%AD%A5-%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>你不知道的js-异步-事件循环</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E4%BD%A0%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84js-%E5%BC%82%E6%AD%A5-%E4%BB%A3%E7%A0%81%E7%BC%96%E5%86%99.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>你不知道的js-异步-代码编写</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E4%BD%A0%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84js.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>你不知道的js</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E5%89%8D%E7%AB%AF%E6%A8%A1%E5%9D%97%E5%8C%96.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前端模块化</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E6%B5%8F%E8%A7%88%E5%99%A8%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>浏览器垃圾回收</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E6%B7%B1%E5%85%A5babel.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>深入babel</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/js/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>设计模式</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>microFrontend</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/microFrontend/%E4%BB%8B%E7%BB%8D.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>介绍</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/microFrontend/%E5%BE%AE%E5%89%8D%E7%AB%AF%E5%89%8D%E4%B8%96%E4%BB%8A%E7%94%9F.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>微前端前世今生</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/microFrontend/%E6%8B%9F%E5%AE%9A%E5%BE%AE%E5%89%8D%E7%AB%AF%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>拟定微前端架构设计</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/microFrontend/%E6%9E%B6%E6%9E%84%E6%80%9D%E6%83%B3.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>架构思想</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>node</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/node/cheetah-learn.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>cheetah-learn</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/node/cli%E7%9B%B8%E5%85%B3%E5%AD%A6%E4%B9%A0.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>cli相关学习</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>others</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/others/%E7%94%B5%E5%BD%B1-%E5%AF%BC%E6%BC%94%E5%90%8C%E4%B8%80%E4%B8%BB%E9%A2%98%E5%AF%B9%E6%AF%94.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>电影-导演同一主题对比</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>performance</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/performance/serviceWorker.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>serviceWorker</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/performance/ssr.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>ssr</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/performance/webpack%E6%89%93%E5%8C%85%E4%BC%98%E5%8C%96.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>webpack打包优化</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/performance/%E6%85%95%E8%AF%BE%E7%BD%91web%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>慕课网web性能优化</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>typescript</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/typescript/vue2%E5%8A%A0ts.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>vue2加ts</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>vue</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/create-vue%E8%84%9A%E6%89%8B%E6%9E%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>create-vue脚手架</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/esbuild%E4%BD%BF%E7%94%A8.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>esbuild使用</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/keep-alive%E5%8E%9F%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>keep-alive原理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/vue-router%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>vue-router实现原理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E6%A8%A1%E6%9D%BF%E7%BC%96%E8%AF%91.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>模板编译</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E8%B7%AF%E7%94%B1%E9%A1%B5%E9%9D%A2%E5%8E%86%E5%8F%B2%E6%A0%88%E7%9A%84%E5%A4%84%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>路由页面历史栈的处理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-01%E6%A8%A1%E6%9D%BF%E8%AF%AD%E6%B3%95.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-01模板语法</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-02%E6%95%B0%E6%8D%AE%E9%A9%B1%E5%8A%A8%E8%A7%86%E5%9B%BE.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-02数据驱动视图</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-03render%E5%87%BD%E6%95%B0.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-03render函数</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-04%E5%86%85%E7%BD%AE%E6%8C%87%E4%BB%A4.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-04内置指令</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-05filter%E5%A4%9A%E4%BD%99%E5%90%97.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-05filter多余吗</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-06computer.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-06computer</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-07watch.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-07watch</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-08%E7%BB%84%E4%BB%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-08组件</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-09%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-09生命周期</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-10ref%E6%98%AF%E4%BB%80%E4%B9%88.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-10ref是什么</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-11nextTick.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-11nextTick</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-8%E7%BB%84%E4%BB%B6%E9%80%9A%E4%BF%A1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-8组件通信</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-vue.use.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-vue.use</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue/%E9%87%8D%E5%AD%A6vue-%E5%8A%A8%E7%94%BB%E5%86%85%E7%BD%AE%E7%BB%84%E4%BB%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学vue-动画内置组件</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>vue3</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue3/elementPlus.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>elementPlus</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue3/%E5%85%A5%E9%97%A8.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>入门</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/vue3/%E5%89%8D%E6%9C%9F%E5%88%9D%E5%A7%8B%E5%8C%96%E9%A1%B9%E7%9B%AE%E6%AD%A5%E9%AA%A4.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>前期初始化项目步骤</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>webComponents</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/webComponents/1.%20webComponent%E4%BB%8B%E7%BB%8D.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>1. webComponent介绍</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webComponents/2.%20customElements.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>2. customElements</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>webpack</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>1</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/mini%E6%89%93%E5%8C%85%E5%B7%A5%E5%85%B7.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>mini打包工具</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E8%87%AA%E5%B7%B1%E7%9A%84%E8%84%9A%E6%89%8B%E6%9E%B6.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>实现一个自己的脚手架</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E9%87%8D%E5%AD%A6webpack-01%E6%89%93%E5%8C%85%E5%B7%A5%E5%85%B7%E7%9A%84%E6%80%9D%E8%80%83.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学webpack-01打包工具的思考</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E9%87%8D%E5%AD%A6webpack-02%E6%A8%A1%E5%9D%97%E5%8C%96%E5%8E%9F%E7%90%86.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学webpack-02模块化原理</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E9%87%8D%E5%AD%A6webpack-03loader.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学webpack-03loader</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E9%87%8D%E5%AD%A6webpack-04plugin.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学webpack-04plugin</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/webpack/%E9%87%8D%E5%AD%A6webpack-05HMR%E7%83%AD%E6%9B%B4%E6%96%B0.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>重学webpack-05HMR热更新</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>week</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/week/202110-1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>202110-1</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/week/202110-2.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>202110-2</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/week/202111-1.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>202111-1</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/week/%E7%BC%93%E5%AD%98%E5%B7%A5%E5%85%B7%E6%96%B9%E6%B3%95%E6%80%9D%E8%B7%AF.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>缓存工具方法思路</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><div class="group" data-v-4d03be81><section class="VPSidebarGroup collapsible collapsed" data-v-4d03be81 data-v-d37d8138><div class="title" role="button" data-v-d37d8138><h2 class="title-text" data-v-d37d8138>work</h2><div class="action" data-v-d37d8138><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 24 24" class="icon minus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2zM20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg><svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon plus" data-v-d37d8138><path d="M19,2H5C3.3,2,2,3.3,2,5v14c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V5C22,3.3,20.7,2,19,2z M20,19c0,0.6-0.4,1-1,1H5c-0.6,0-1-0.4-1-1V5c0-0.6,0.4-1,1-1h14c0.6,0,1,0.4,1,1V19z"></path><path d="M16,11h-3V8c0-0.6-0.4-1-1-1s-1,0.4-1,1v3H8c-0.6,0-1,0.4-1,1s0.4,1,1,1h3v3c0,0.6,0.4,1,1,1s1-0.4,1-1v-3h3c0.6,0,1-0.4,1-1S16.6,11,16,11z"></path></svg></div></div><div class="items" data-v-d37d8138><!--[--><!--[--><a class="VPLink link link" href="/giteepage_blog/work/ios%E5%B0%8F%E7%99%BD%E6%9D%A1%E9%97%AE%E9%A2%98.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>ios小白条问题</span><!--]--><!----></a><!----><!--]--><!--[--><a class="VPLink link link" href="/giteepage_blog/work/%E4%BB%8Eurl%E8%8E%B7%E5%8F%96%E5%9B%BE%E7%89%87%E5%AE%BD%E9%AB%98.html" style="padding-left:0px;" data-v-3ab72ab5 data-v-bf6d4382><!--[--><span class="link-text" data-v-3ab72ab5>从url获取图片宽高</span><!--]--><!----></a><!----><!--]--><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-fc91a531 data-v-1f75116f><div class="VPDoc has-sidebar has-aside" data-v-1f75116f data-v-4abc8cb4><div class="container" data-v-4abc8cb4><div class="aside" data-v-4abc8cb4><div class="aside-curtain" data-v-4abc8cb4></div><div class="aside-container" data-v-4abc8cb4><div class="aside-content" data-v-4abc8cb4><div class="VPDocAside" data-v-4abc8cb4 data-v-26b03bfc><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" data-v-26b03bfc data-v-e4230e59><div class="content" data-v-e4230e59><div class="outline-marker" data-v-e4230e59></div><div class="outline-title" data-v-e4230e59>On this page</div><nav aria-labelledby="doc-outline-aria-label" data-v-e4230e59><span class="visually-hidden" id="doc-outline-aria-label" data-v-e4230e59> Table of Contents for current page </span><ul class="root" data-v-e4230e59 data-v-dc579305><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-26b03bfc></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-4abc8cb4><div class="content-container" data-v-4abc8cb4><!--[--><!--]--><main class="main" data-v-4abc8cb4><div style="position:relative;" class="vp-doc _giteepage_blog_http_http%E7%BC%93%E5%AD%98" data-v-4abc8cb4><div><h1 id="http缓存" tabindex="-1">http缓存 <a class="header-anchor" href="#http缓存" aria-hidden="true">#</a></h1><p>关于http缓存的背景以及意义，这里跳过不讲(主要由于http的无状态导致的性能损耗)，直接从http缓存的流程和如何配置讲起 目前正在啃《图解http协议》之后会按照书本的每一章出文章，对于常见的http相关问题会单独讲(挖坑+1)</p><p>先记住几个概念</p><ul><li>强缓存: 浏览器不发起http请求，直接从浏览器缓存中读取资源</li><li>协商缓存：浏览器发起http请求，服务端只返回状态码让浏览器读取缓存</li><li>http1：最早期的http协议</li><li>http1.1：优化缓存策略升级后的http协议</li></ul><h2 id="浏览器http缓存流程" tabindex="-1">浏览器http缓存流程 <a class="header-anchor" href="#浏览器http缓存流程" aria-hidden="true">#</a></h2><blockquote><p>这里忽略浏览器一个请求发起的所有过程(DNS解析、TCP、HTTP)</p></blockquote><p>浏览器在客户端，会有一个内存空间用于存储有http缓存相关头的每次有响应的http请求</p><p>在下一次请求发出前，浏览器会到内存空间找到相同url的http请求 如果上一次http请求的响应头中有http缓存相关的字段 将判断是否命中强缓存，如果是则不发起请求，如果不是则把缓存相关的响应头字段处理成相应的请求头字段发出 即</p><ul><li>我们可以把http强缓存过程当成是浏览器发起请求前发生的</li><li>http协商缓存过程当成是服务端响应的时候发生的</li></ul><p>以上仅是浅显的猜测，具体的流程未知</p><h2 id="强缓存" tabindex="-1">强缓存 <a class="header-anchor" href="#强缓存" aria-hidden="true">#</a></h2><p>如上的浏览器http缓存流程，http强缓存发生在浏览器发起请求前</p><p>强缓存分为 <code>Disk Cache (存放在硬盘中)</code>和 <code>Memory Cache (存放在内存中)</code>，存放的位置是由浏览器控制的。</p><h3 id="expires" tabindex="-1">Expires <a class="header-anchor" href="#expires" aria-hidden="true">#</a></h3><p>用于设置静态资源的<code>过期时间</code>。它的值一个<code>GMT格式</code>的时间字符串，比如<code>expires:Fri, 27 Jul 2029 13:38:54 GMT</code>。 这个时间代表着这个资源的失效时间，在此时间之前命中缓存。</p><p>缺点： 浏览器端时间和服务器时间不一致的时候，会有缓存有效期不准的问题(是双方各自的绝对时间)</p><h3 id="cache-control" tabindex="-1">Cache-Control <a class="header-anchor" href="#cache-control" aria-hidden="true">#</a></h3><blockquote><p>Cache-Control 是 HTTP/1.1 中新增的属性，在请求头和响应头中都可以使用 优先级在<code>Expires</code>之上,即如果有<code>Cache-Control</code>，将无视<code>Expires</code><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control" target="_blank" rel="noreferrer">Cache-Control MDN</a></p></blockquote><p>常用的属性值如有：</p><ul><li>no-store：禁止使用缓存（包括协商缓存），每次都向服务器请求最新的资源</li><li>no-cache：不使用强缓存，需要与服务器验证缓存是否新鲜</li><li>max-age：单位是秒，缓存时间计算的方式是距离发起的时间的秒数，超过间隔的秒数缓存失效。与Expires相反，时间是相对于请求的时间。</li><li>s-max-age：覆盖max-age或者Expires头，但是仅适用于共享缓存(比如各个代理)，私有缓存会忽略它。</li><li>private：专用于个人的缓存，中间代理、CDN 等不能缓存此响应（默认值）</li><li>public：响应可以被中间代理、CDN 等缓存</li><li>must-revalidate：在缓存过期前可以使用，过期后必须向服务器验证</li></ul><p>Cache-Control的<code>max-age</code>是一个相对时间，例如<code>3600</code>，代表着资源的有效期是3600秒一个小时。由于是相对时间，并且都是与客户端时间比较，所以服务器与客户端时间偏差也不会导致问题。</p><p>流程大概可以是： 浏览器发起请求前，到内存中找到了上一次相同url相应的请求，并且上一次响应头中有<code>max-age</code>是3600秒，即一个小时，并且内存中的请求都会有个每次发起http请求都会生成的date，浏览器用当前时间和内存中的请求时间，相减得到的秒数判断是否取内存中的相应结果。</p><p>👆 所以，第三第四次以及之后的请求都是与第一次请求(缓存下来的http)的时间做比较的，并不是与上一次请求做比较</p><blockquote><p>根据http标准，如果请求头不携带任何关于缓存的标记而响应头有缓存相关字段，则缓存时间等于当前时间和 Last-Modified时间的差值的10%，等同于cache-control=max-age=（date - Last-Modified）/ 10，通过fiddler抓包可看到英文原文：No explicit HTTP Cache Lifetime information was provided.Heuristic expiration policies suggest defaulting to: 10% of the delta between Last-Modified and Date.</p></blockquote><p>👆 一般请求都会设置上的，这种属于很极端的情况吧(面试造火箭？)</p><h2 id="协商缓存" tabindex="-1">协商缓存 <a class="header-anchor" href="#协商缓存" aria-hidden="true">#</a></h2><blockquote><p>在浏览器决定不取强缓存时，发起了请求，服务端将根据请求头中http缓存相应字段，做出对应的响应</p></blockquote><h3 id="时间-last-modified-if-modified-since" tabindex="-1">时间 Last-Modified/If-Modified-Since <a class="header-anchor" href="#时间-last-modified-if-modified-since" aria-hidden="true">#</a></h3><blockquote><p>协商缓存需要服务端配合 浏览器第一次请求一个资源的时候，服务器返回的header中会加上<code>Last-Modify</code>，<code>Last-modify</code>是一个时间标识该资源的最后修改时间，例如<code>last-modified:Fri, 20 Dec 2019 03:34:57 GMT</code>。</p></blockquote><p>第一次响应时，服务端需要在响应头中返回协商缓存相关的字段，浏览器完成第一次请求响应，会缓存相关的协商缓存字段</p><p>流程大概可以是：</p><ul><li>浏览器发起请求前，到内存中找到了上一次相同url相应的请求，决定不走强缓存。将找到内存中的响应头中协商缓存相关的字段<code>Last-Modify</code>，拼接到这次发起的http请求头中<code>If-Modified-Since</code>，开始发起请求。</li><li>服务器接收到请求，检查请求头中的协商缓存相关字段，发现有<code>If-Modified-Since</code>，拿url相应的资源修改时间做比较，发现修改时间是相同的则直接返回304响应码，让浏览器取缓存。否则响应真实资源，并且响应头会带上新的<code>Last-Modify</code></li></ul><p>缺点：</p><ul><li>不同服务器资源的修改时间精度可能不同，存在相同时间资源内容变更的情况。导致服务器判断本次请求返回304（后果严重，用户访问的是错误内容）</li><li>资源内容没有实质变化，但是修改时间更新了，如加了回车或是空格，如服务器资源是全量删除全量更新的。导致服务器判断本次请求返回200真实请求 (实际让浏览器取缓存就可以,性能浪费)</li></ul><h3 id="etag-if-none-match" tabindex="-1">Etag/If-None-Match <a class="header-anchor" href="#etag-if-none-match" aria-hidden="true">#</a></h3><blockquote><p>Etag/If-None-Match返回的是一个校验码（ETag: entity tag）。 Etag：服务器响应请求时，告诉浏览器当前资源在服务器的唯一标识（生成规则由服务器定义）。nginx中，etag会默认增加，如果需要关闭，需要在配置文件中设置：etag off;</p></blockquote><p>与👆 <code>时间 Last-Modified/If-Modified-Since</code> 类似，这种协商缓存比对流程相同，并且是互斥的关系，etag的优先级更高(即有etag将无视<code>Last-Modified</code>)</p><p>流程大概可以是：</p><ul><li>浏览器发起请求前，到内存中找到了上一次相同url相应的请求，决定不走强缓存。将找到内存中的响应头中协商缓存相关的字段<code>Etag</code>，拼接到这次发起的http请求头中<code>If-None-Match</code>，开始发起请求。</li><li>服务器接收到请求，检查请求头中的协商缓存相关字段，发现有<code>If-None-Match</code>，拿url相应的资源的唯一标识做比较，发现资源唯一标识是相同的则直接返回304响应码，让浏览器取缓存。否则响应真实资源，并且响应头会带上新的<code>Etag</code></li></ul><p>ETag 有强弱校验之分，如果 hash 码是以 &quot;W/&quot; 开头的一串字符串，说明此时协商缓存的校验是弱校验的，只有服务器上的文件差异（根据 ETag 计算方式来决定）达到能够触发 hash 值后缀变化的时候，才会真正地请求资源</p><h2 id="强缓存和协商缓存的整体流程图" tabindex="-1">强缓存和协商缓存的整体流程图 <a class="header-anchor" href="#强缓存和协商缓存的整体流程图" aria-hidden="true">#</a></h2><p><img src="https://kingan-md-img.oss-cn-guangzhou.aliyuncs.com/blog/20211226174336.png" alt="http缓存的流程"></p><p>不走强缓存的几种方式</p><h2 id="pragma" tabindex="-1">Pragma <a class="header-anchor" href="#pragma" aria-hidden="true">#</a></h2><blockquote><p>Pragma 只有一个属性值，就是 no-cache 注意不是属于Cache-Control下的某种场景，而是和Cache-Control、Expires 同级别的控制参数，</p></blockquote><p>效果和 Cache-Control 中的 no-cache 一致，不使用强缓存，但是会协商缓存，需要与服务器验证缓存是否新鲜，在 3 个头部属性中的优先级最高。</p><h2 id="使用nodejs实操http缓存策略" tabindex="-1">使用nodejs实操http缓存策略 <a class="header-anchor" href="#使用nodejs实操http缓存策略" aria-hidden="true">#</a></h2><h3 id="构建http服务" tabindex="-1">构建http服务 <a class="header-anchor" href="#构建http服务" aria-hidden="true">#</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> http </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">http</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fs </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">fs</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> server </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> http</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createServer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">resp</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// resp.writeHead(200, {</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">//   &quot;Content-type&quot;: &quot;text/html&quot; // 不返回 浏览器也可以猜测出类型，但是一般都返回</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// });</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">server</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">listen</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">9080</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Server runing at part: 9080</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>👆 用nodejs起一个服务 <code>localhost:9080</code> 访问这个地址，会读取本地文件中的 <code>dist/index.html</code>，返回回去</p><ul><li><code>fs.readFileSync()</code> 是同步方法，并且不需要await，第二个参数文件类型必须写上<code>utf8</code> 不可省略</li><li><code>nodejs</code>的<code>http服务</code>默认返回<code>状态码200</code>，本次示例可以不设置响应状态</li><li><code>Content-type</code>浏览器也可以根据内容猜测，但是会有猜测性能损耗，实际场景必须带上相应类型，本次示例不设置</li><li>完整http服务还要做好各种常规异常处理,本次示例不设置 <ul><li>启服务器失败</li><li>逻辑异常500</li><li>资源不存在404</li><li>...</li></ul></li></ul><h3 id="设置强缓存expires" tabindex="-1">设置强缓存Expires <a class="header-anchor" href="#设置强缓存expires" aria-hidden="true">#</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> http </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">http</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fs </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">fs</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> server </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> http</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createServer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">resp</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">time</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">new</span><span style="color:#F07178;"> </span><span style="color:#82AAFF;">Date</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">time</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setTime</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">time</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">getTime</span><span style="color:#F07178;">() </span><span style="color:#89DDFF;">+</span><span style="color:#F07178;"> (</span><span style="color:#F78C6C;">10</span><span style="color:#89DDFF;">*</span><span style="color:#F78C6C;">1000</span><span style="color:#F07178;">)) </span><span style="color:#676E95;font-style:italic;">// 时间戳计算单位是毫秒</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">res</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setHeader</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Expires</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">time</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toUTCString</span><span style="color:#F07178;">())</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">server</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">listen</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">9080</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Server runing at part: 9080</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>👆 设置10秒后的到期时间</p><ul><li>设置到期时间是UTC日期格式，因此使用<code>toUTCString()</code>转化</li><li><code>toUTCString()</code>是日期对象的方法，因此计算时间要用<code>setTime()</code></li><li>日期对象转时间戳计算的单位是毫秒</li></ul><p>浏览器验证发现刷新虽然每次响应头都有<code>Expires</code>,但是每次请求头都会带上<code>Cache-Control: max-age=0</code> 我们上面讲到了<code>cache-control</code>优先级高于<code>expires</code>，所以每次请求都不会走强缓存</p><p>这个请求头的<code>Cache-Control</code>，是浏览器地址栏直接发起get请求默认带上的</p><p>解决办法</p><ul><li>改写成ajax请求访问我们的http服务，而不用浏览器地址栏直接get请求</li><li>浏览器开着一个get请求，再新开一个标签页，提前打开控制台，输入地址再次直接发起get请求。并且新开的标签页也不能刷新测试，只能重复开新的标签页测试，这样可以让浏览器不带上<code>max-age=0</code></li></ul><h3 id="设置强缓存cache-control-max-age" tabindex="-1">设置强缓存<code>Cache-Control: max-age</code> <a class="header-anchor" href="#设置强缓存cache-control-max-age" aria-hidden="true">#</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> http </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">http</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fs </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">fs</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> server </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> http</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createServer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">resp</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">res</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setHeader</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Cache-Control</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">max-age=10</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">server</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">listen</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">9080</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Server runing at part: 9080</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>👆 设置10秒后的相对时间到期 同样用新开标签的形式进行验证</p><h3 id="设置协商缓存最后修改日期" tabindex="-1">设置协商缓存最后修改日期 <a class="header-anchor" href="#设置协商缓存最后修改日期" aria-hidden="true">#</a></h3><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> http </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">http</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fs </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">fs</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> server </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> http</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createServer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">resp</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">stats</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">statSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastModified</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">stats</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">mtime</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">toUTCString</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// resp.setHeader(&#39;Cache-Control&#39;,&#39;max-age=5&#39;)</span></span>
<span class="line"><span style="color:#89DDFF;">  </span><span style="color:#676E95;font-style:italic;">// 如果要找的资源修改时间等于请求头中的缓存修改时间，则返回304</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">requestModified</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">headers</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">if-modified-since</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">requestModified</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">requestModified</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">lastModified</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">statusCode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">304</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setHeader</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Last-Modified</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">lastModified</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 浏览器请求头会自动带上 if-modified-since</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">server</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">listen</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">9080</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Server runing at part: 9080</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>协商缓存会发现 状态码设置不生效，但是资源size可以看出来是走了304的</p><p>在html上加外链css尝试，可以看到有304状态生效，但是等一会再刷新，状态变成了200 资源size还是可以走了304 很奇怪，只有状态设置不生效 到safire浏览器尝试，发现可以正常304，这里的原因不明，以后知道了再回来补吧。。。</p><p>不影响我们http缓存测试</p><h3 id="设置协商缓存etag" tabindex="-1">设置协商缓存Etag <a class="header-anchor" href="#设置协商缓存etag" aria-hidden="true">#</a></h3><p>可以先用上面代码示例来验证modified的缺点，如上所述，文件内容没有修改，也会重新请求，删除然后新建也会重新请求，精度在1秒内会请求旧的资源</p><div class="language-js"><button title="Copy Code" class="copy"></button><span class="lang">js</span><pre class="shiki material-palenight"><code><span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> http </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">http</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> fs </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">fs</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> crypto </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> </span><span style="color:#82AAFF;">require</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">crypto</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C792EA;">const</span><span style="color:#A6ACCD;"> server </span><span style="color:#89DDFF;">=</span><span style="color:#A6ACCD;"> http</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createServer</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">(</span><span style="color:#A6ACCD;font-style:italic;">request</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;font-style:italic;">resp</span><span style="color:#89DDFF;">)</span><span style="color:#C792EA;">=&gt;</span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setHeader</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Cache-Control</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">max-age=0</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">buffer</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hash</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">crypto</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">createHash</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">md5</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">hash</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">update</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">buffer</span><span style="color:#89DDFF;">,</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">md5</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">hash</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">digest</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">hex</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">requestEtage</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">request</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">headers</span><span style="color:#F07178;">[</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">if-none-match</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">]</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;font-style:italic;">if</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">requestEtage</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">&amp;&amp;</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">requestEtage</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">===</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">md5</span><span style="color:#F07178;">) </span><span style="color:#89DDFF;">{</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#A6ACCD;">statusCode</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#F78C6C;">304</span><span style="color:#89DDFF;">;</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">()</span></span>
<span class="line"><span style="color:#F07178;">    </span><span style="color:#89DDFF;font-style:italic;">return</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#89DDFF;">}</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">setHeader</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">etag</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#A6ACCD;">md5</span><span style="color:#F07178;">) </span><span style="color:#676E95;font-style:italic;">// 浏览器请求头会自动带上 if-modified-since</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#C792EA;">const</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;"> </span><span style="color:#89DDFF;">=</span><span style="color:#F07178;"> </span><span style="color:#A6ACCD;">fs</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">readFileSync</span><span style="color:#F07178;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">./dist/index.html</span><span style="color:#89DDFF;">&#39;</span><span style="color:#89DDFF;">,</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">utf8</span><span style="color:#89DDFF;">&#39;</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#F07178;">  </span><span style="color:#A6ACCD;">resp</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">end</span><span style="color:#F07178;">(</span><span style="color:#A6ACCD;">html</span><span style="color:#F07178;">)</span></span>
<span class="line"><span style="color:#89DDFF;">}</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#A6ACCD;">server</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">listen</span><span style="color:#A6ACCD;">(</span><span style="color:#F78C6C;">9080</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"><span style="color:#A6ACCD;">console</span><span style="color:#89DDFF;">.</span><span style="color:#82AAFF;">log</span><span style="color:#A6ACCD;">(</span><span style="color:#89DDFF;">&#39;</span><span style="color:#C3E88D;">Server runing at part: 9080</span><span style="color:#89DDFF;">&#39;</span><span style="color:#A6ACCD;">)</span></span>
<span class="line"></span></code></pre></div><p>为了保证 lastModified 不影响缓存，把通过 Last-Modified/If-Modified-Since 请求头删除 然后修改 html，增加一个空格后再删除一个空格，保持文件内容不变，但文件的修改时间改变，发起请求，由于生成 ETag 的方式是通过对文件内容进行 MD5 加密生成，所以虽然修改时间变化了，请求返回了 304 ，读取浏览器缓存。</p><p>采用的是对文件进行 MD5 加密来计算其 hash 值。</p><p>注：只是为了演示用，实际计算不是通过 MD5 加密的，Apache 默认通过 FileEtag 中 FileEtag INode Mtime Size 的配置自动生成 ETag，用户可以通过自定义的方式来修改文件生成 ETag 的方式。</p><h2 id="关于资源hash解决的问题" tabindex="-1">关于资源hash解决的问题 <a class="header-anchor" href="#关于资源hash解决的问题" aria-hidden="true">#</a></h2><p>对于img，css，js，fonts等非html资源，我们可以直接考虑max-age配置的时间可以尽可能久，类似于缓存规则案例中，<code>cache-control: max-age=31535000</code>配置365天的缓存 需要注意的是，这样配置并不代表这些资源就一定一年不变，其根本原因在于目前前端构建工具在静态资源中都会加入戳的概念（例如，webpack中的[hash]，gulp中的gulp-rev） 每次修改均会改变文件名或增加query参数，本质上改变了请求的地址，也就不存在缓存更新的问题 每次都是一次新的强缓存</p><h2 id="dns缓存" tabindex="-1">DNS缓存 <a class="header-anchor" href="#dns缓存" aria-hidden="true">#</a></h2><p>浏览器请求域名</p><ol><li>浏览器从自身的DNS缓存中去查找</li><li>浏览器从本地host文件查找</li><li>浏览器从操作系统里的DNS缓存中查找</li><li>浏览器请求本地域名服务器（例如电信）</li><li>浏览器请求DNS服务器递归查找</li></ol><p>此时获得源服务器IP，以及源服务器根据域名配置的负载均衡服务器CDN策略服务器IP 本地域名服务器将不直接返回源服务器IP，而是去访问CDN服务器，负载均衡后返回的中间服务器(代理服务器IP/CDN服务器？)</p><p>因此浏览器拿到并访问的是中间服务器IP(在浏览器显示的是域名)</p><p>关于域名解析过程(由右往左) <img src="https://kingan-md-img.oss-cn-guangzhou.aliyuncs.com/blog/20211224112314.png" alt="关于域名解析过程"></p><h2 id="cdn缓存" tabindex="-1">CDN缓存 <a class="header-anchor" href="#cdn缓存" aria-hidden="true">#</a></h2><p>上述的http缓存都是客户端自己的缓存，即只有当我访问过一次并缓存才能走缓存 而CDN则可以做到多个客户端，只要有一个人访问，CDN服务器就可以缓存下来，下次其他人再访问到CDN就直接给你CDN中的缓存 当然客户端访问CDN，还是一个http请求，只不过比直接访问源服务器要更快</p><p>缓存CDN缓存的建议观看 <a href="https://www.bilibili.com/video/BV1jS4y197zi" target="_blank" rel="noreferrer">什么是CDN？CDN能为我们做什么？我们为什么要了解他？-bilibili</a></p><p>当浏览器向CDN节点请求数据时，CDN节点会判断缓存数据是否过期，若缓存数据并没有过期，则直接将缓存数据返回给客户端；否则，CDN节点就会向服务器发出回源请求，从服务器拉取最新数据，更新本地缓存，并将最新数据返回给客户端。</p><blockquote><p>CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间，为用户提供更精细化的缓存管理</p></blockquote><p><img src="https://kingan-md-img.oss-cn-guangzhou.aliyuncs.com/blog/20211229194429.png" alt="腾讯云CDN设置"> 👆腾讯云CDN设置，不仅可以沿用源服务端设置的缓存策略，还可以自定义缓存策略</p><p><strong>当CDN有自定义强缓存时间，并且源服务器更新了资源怎么办?</strong></p><p>如果我们http缓存设置<code>cache-control: max-age=600</code>，即缓存10分钟，但cdn缓存配置中设置文件缓存时间为1小时，那么就会出现如下情况，文件被访问后第12分钟修改并上传到服务器，用户重新访问资源，响应码会是304，对比缓存未修改，资源依然是旧的，一个小时后再次访问才能更新为最新资源</p><p>当我们必须要在缓存期内修改文件，并且不想影响用户体验，那么我们可以使用cdn服务商提供的强制更新缓存功能，主要注意的是，这里的强制更新是更新服务端缓存，http缓存依然按照http头部规则进行自己的缓存处理，并不会受到影响。</p><p><strong>CDN其他应用举例</strong> 除了静态内容，CDN服务器还可以获取动态内容，如服务器时间，客户端访问源服务器(中间链路长可能断连)时间可能不准或是获取不到 那就让客户端获取CDN的服务器时间，源服务器也以CDN服务器时间为准</p><h2 id="hash" tabindex="-1">hash <a class="header-anchor" href="#hash" aria-hidden="true">#</a></h2><blockquote><p>在讨论理想缓存模型前，我们先看看资源hash的采用形式</p></blockquote><p>在webpack等打包工具中，hash的生成规则分为: <code>hash</code>、<code>contenhash</code>... 我们只考虑最理想的<code>contentHash</code></p><p>浏览器识别资源可以考虑缓存的标识是url，包括url参数</p><h3 id="query-hash" tabindex="-1">query-hash <a class="header-anchor" href="#query-hash" aria-hidden="true">#</a></h3><p>那么我们可以利用参数做hash <code>myapp/homePage.js?hash=1234</code> 这样就能通过更新hash来使浏览器从重新发起全新请求(不走协商缓存,会是完全首次请求)</p><p>缺点</p><ul><li>hash的值需要我们自己拼上资源请求,如:html中的srcipt是带参数的、异步js的require带参数</li><li>hash的值简单做法每次打包都是新的hash，会导致没更新的资源也重新请求。或者靠我们自己实现好的hash对应关系，只更新需要更新的hash</li><li>覆盖式部署,因为hash为参数，部署相同资源将是同名资源，上服务器会覆盖旧资源。如果资源要分类上传CDN服务器，会出现上传不同类资源更新先后顺序问题</li></ul><p>优点</p><ul><li>覆盖式部署，不会产生无用的旧资源</li></ul><h3 id="name-hash" tabindex="-1">name-hash <a class="header-anchor" href="#name-hash" aria-hidden="true">#</a></h3><p>把hash直接作为文件名 <code>myapp/homePage.1234.js</code> 减少我们自己实现hash和文件对应关系的工作量，我们只需要把contenthash输出到文件名，就可以做到精确的文件是否更新标识</p><p>优点</p><ul><li>可以精确每个文件内容是否修改过的标识</li><li>如果资源分类上传CDN服务器，因为旧资源新资源会并存，所以先把被依赖被请求的资源上传，再上传入口资源就可以避免出现问题</li></ul><p>缺点</p><ul><li>随着时间推移，相同资源文件会留存很多份旧的，并且不好随便删除，需要制订好清除规则</li></ul><h3 id="解决问题" tabindex="-1">解决问题 <a class="header-anchor" href="#解决问题" aria-hidden="true">#</a></h3><blockquote><p>我们尝试不考虑复杂度，对上述两种方案做出合适的解决方案</p></blockquote><ol><li><p>query-hash hash和文件的对应关系</p></li><li><p>CDN+覆盖式部署</p></li><li><p>name-hash，清除旧资源机制</p></li></ol><h2 id="理想缓存策略" tabindex="-1">理想缓存策略 <a class="header-anchor" href="#理想缓存策略" aria-hidden="true">#</a></h2><p><img src="https://kingan-md-img.oss-cn-guangzhou.aliyuncs.com/blog/20211229174408.png" alt="理想缓存策略"></p><p>理想缓存策略，将资源简单的分为两种</p><ul><li>带hash/版本号的资源(html、css、js、图片、字体等)</li><li>不带hash/版本号的资源(html、css、js、图片、字体等)</li></ul><p>带hash的资源，相当于我们把浏览器是否要取缓存的判断交给了打包工具，更新了资源，浏览器就重新获取。 这里用service Worker，替代强缓存365天，只是为了资源可以离线获取，实际上用永久http强缓存相同效果</p><p>不带hash的资源，设置强缓存10分钟，协商缓存依靠etag。并且靠CDN缓存，CDN缓存在上面讲过，缓存机制和浏览器是类似</p><p>还有不缓存的如html资源，这里忽略</p><p>当然，这只是理想模型，实际场景要考虑很多因素</p><h2 id="其他拓展" tabindex="-1">其他拓展 <a class="header-anchor" href="#其他拓展" aria-hidden="true">#</a></h2><h3 id="浏览器的gzip" tabindex="-1">浏览器的gzip <a class="header-anchor" href="#浏览器的gzip" aria-hidden="true">#</a></h3><ul><li>给静态资源服务器http开启gzip,(nodejs来压缩？) 和缓存一样，只要有标识，浏览器就会自己去做解压</li></ul><p>需要注意的是压缩的步骤由谁去做</p><h3 id="webpack的hash、chunkhash和contenthash区别" tabindex="-1">webpack的hash、chunkhash和contenthash区别 <a class="header-anchor" href="#webpack的hash、chunkhash和contenthash区别" aria-hidden="true">#</a></h3><ul><li>hash：根据打包中所有的文件计算出的hash值。在一次打包中，所有出口文件的filename获得的[hash]都是一样的。</li><li>chunkhash：根据打包过程中当前chunk计算出的hash值。如果Webpack配置是多入口配置，那么通常会生成多个chunk，每个chunk对应的出口filename获得的[chunkhash]是不一样的</li><li>contenthash有点像chunkhash，是根据打包时CSS内容计算出的hash值。一般在使用提取CSS的loader或plugin的时候，我们使用contenthash</li></ul><h2 id="参考资料" tabindex="-1">参考资料 <a class="header-anchor" href="#参考资料" aria-hidden="true">#</a></h2><ul><li><a href="https://juejin.cn/post/6844903709982490638" target="_blank" rel="noreferrer">http缓存与cdn缓存配置指南</a></li><li><a href="https://zhuanlan.zhihu.com/p/24467558" target="_blank" rel="noreferrer">【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法</a></li><li><a href="https://zhuanlan.zhihu.com/p/65722520" target="_blank" rel="noreferrer">聊聊 CDN 缓存与浏览器缓存</a></li><li><a href="https://naluduo.vip/Web-Performance-Optimization/cache" target="_blank" rel="noreferrer">微谈 Web 前端性能优化-缓存篇</a></li><li><a href="https://zhuanlan.zhihu.com/p/28113197" target="_blank" rel="noreferrer">设计一个无懈可击的浏览器缓存方案：关于思路，细节，ServiceWorker，以及HTTP/2</a></li></ul></div></div></main><!--[--><!--]--><footer class="VPDocFooter" data-v-4abc8cb4 data-v-d9051656><!----><div class="prev-next" data-v-d9051656><div class="pager" data-v-d9051656><a class="pager-link prev" href="/giteepage_blog/http/http3.html" data-v-d9051656><span class="desc" data-v-d9051656>Previous page</span><span class="title" data-v-d9051656>http3</span></a></div><div class="has-prev pager" data-v-d9051656><a class="pager-link next" href="/giteepage_blog/innermanage/%E5%86%85%E7%AE%A1%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B.html" data-v-d9051656><span class="desc" data-v-d9051656>Next page</span><span class="title" data-v-d9051656>内管前端工程</span></a></div></div></footer><!--[--><!--]--></div></div></div></div></div><!----><!--[--><!--]--></div></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"interview_前端面试之道-事件机制.md\":\"7e896362\",\"interview_前端面试之道-安全.md\":\"518a9d1e\",\"interview_前端面试之道-变量提升.md\":\"d7eb33bb\",\"vue_重学vue-vue.use.md\":\"23728968\",\"week_202110-1.md\":\"c8bfaa56\",\"vue_重学vue-03render函数.md\":\"4376e77c\",\"vue_重学vue-08组件.md\":\"e00bd1e9\",\"jiagou_移动端响应式开发单位设计.md\":\"e8ab96d1\",\"week_202111-1.md\":\"5e3ace88\",\"js_dayformat正则的使用.md\":\"b7e5888a\",\"webpack__草稿.md\":\"18b32a5c\",\"interview_前端面试之道-缓存.md\":\"0a35938d\",\"webpack_mini打包工具.md\":\"2e38dd52\",\"interview_前端面试之道-思考题.md\":\"17fae964\",\"vue_重学vue-04内置指令.md\":\"53c53243\",\"webpack_重学webpack-01打包工具的思考.md\":\"172b87a9\",\"interview_面试-架构.md\":\"5456aa4f\",\"work_从url获取图片宽高.md\":\"e34f08be\",\"interview_手写系列-new原理.md\":\"1863e0ee\",\"interview_js基础.md\":\"738e9553\",\"week__0todo.md\":\"4c48af54\",\"interview_前端面试之道-继承.md\":\"8e46d918\",\"interview_手写系列-instanceof.md\":\"2452a995\",\"performance_慕课网web性能优化.md\":\"3bbae927\",\"node_cli相关学习.md\":\"e6e2a2f4\",\"performance_serviceworker.md\":\"d3b6b19f\",\"interview_前端面试之道-浏览器原理.md\":\"e08da152\",\"performance_webpack打包优化.md\":\"b41a3b76\",\"http_http3.md\":\"473095a6\",\"interview_前端面试之道-跨域.md\":\"b7c7c1b2\",\"interview_手写系列-lru缓存算法.md\":\"0dfff35a\",\"http_http缓存.md\":\"9d2bfdf4\",\"js_你不知道的js.md\":\"27389cc6\",\"jiagou_monorepo.md\":\"42b54c6e\",\"performance_ssr.md\":\"2e98e4cf\",\"interview_前端面试之道-原型.md\":\"b0d07912\",\"week_缓存工具方法思路.md\":\"d9330378\",\"vue_重学vue-动画内置组件.md\":\"4e7e909b\",\"jiagou_自动生成按需导出目录.md\":\"e6c64963\",\"vue_vue-router实现原理.md\":\"87f00784\",\"interview_手写系列-settime模拟setinterval.md\":\"646ce8b6\",\"interview_前端面试之道-js数据类型.md\":\"cb65918b\",\"interview_面试-js.md\":\"9a5cc6fc\",\"interview_手写系列-防抖节流.md\":\"055d08e7\",\"webpack_重学webpack-05hmr热更新.md\":\"acf127cc\",\"interview_手写系列-数组转树.md\":\"2713c8af\",\"interview_前端面试之道-前端监控.md\":\"b04a7877\",\"interview__过.md\":\"24e3ce0c\",\"interview_面试-vue.md\":\"bd176b43\",\"webcomponents_1. webcomponent介绍.md\":\"b1eb6286\",\"interview_前端面试之道-this.md\":\"0ea26554\",\"microfrontend_介绍.md\":\"2c6c1eae\",\"vue3_elementplus.md\":\"b18edd5d\",\"interview_手写系列-发布订阅和观察者.md\":\"6ec2c5e4\",\"webpack_1.md\":\"c785e603\",\"typescript_vue2加ts.md\":\"5c26be15\",\"vue_esbuild使用.md\":\"47e7a31d\",\"interview_手写系列-callbind.md\":\"9b7ab677\",\"interview_前端面试之道-数字精度.md\":\"14928bc6\",\"vue_重学vue-09生命周期.md\":\"14899925\",\"index.md\":\"f143772c\",\"jiagou_从0到1构建符合标准的公共库.md\":\"c98c5c88\",\"vue_重学vue-07watch.md\":\"10a7a031\",\"interview_前端面试之道-0.md\":\"eaad6360\",\"week_202110-2.md\":\"5715e19d\",\"jiagou_切换主题方案.md\":\"e2f4ba65\",\"innermanage_内管前端工程.md\":\"09080b14\",\"webpack_实现一个自己的脚手架.md\":\"ddd7bee0\",\"interview_todo.md\":\"ae73ffe7\",\"interview_手写系列-复杂axios.md\":\"6d9ac3e9\",\"js_proxy.md\":\"44147b13\",\"vue_重学vue-01模板语法.md\":\"dace5069\",\"vue_重学vue-8组件通信.md\":\"f431a9ac\",\"webpack_重学webpack-03loader.md\":\"4e899872\",\"js_设计模式.md\":\"bf9b7e2a\",\"js_object.entries.md\":\"f0f90382\",\"js_你不知道的js-异步-事件循环.md\":\"f0b6048d\",\"others_电影-导演同一主题对比.md\":\"7b537835\",\"js_优雅的class.md\":\"a9dee846\",\"vue_模板编译.md\":\"6a4029f5\",\"jiagou_前端基础建设与架构30讲.md\":\"8e438efe\",\"js_深入babel.md\":\"8dd9c14a\",\"vue_create-vue脚手架.md\":\"2e728b79\",\"microfrontend_拟定微前端架构设计.md\":\"161a4bbb\",\"interview_面试-css.md\":\"3a4255e0\",\"interview_手写系列-深拷贝.md\":\"f3ec01e6\",\"jiagou_深入babel.md\":\"5f4f432d\",\"js_es2020.md\":\"ef20447c\",\"jiagou_搭建组件库.md\":\"d2db9bcb\",\"js_你不知道的js-异步-代码编写.md\":\"db42dfde\",\"interview_手写系列-复杂promise.md\":\"76a98e43\",\"jiagou_表单组件带校验功能.md\":\"ef3b30fa\",\"vue_重学vue-05filter多余吗.md\":\"cbd1ade8\",\"js_serviceworker.md\":\"3ea114bc\",\"vue_重学vue-06computer.md\":\"12dff690\",\"vue_重学vue-11nexttick.md\":\"17a45398\",\"http_http2.md\":\"809d6a46\",\"js_浏览器垃圾回收.md\":\"e00e9a5c\",\"webpack_重学webpack-04plugin.md\":\"e55b4647\",\"microfrontend_微前端前世今生.md\":\"04ad3199\",\"interview_手写系列-map和filter和reduce.md\":\"69a6ec77\",\"vue_路由页面历史栈的处理.md\":\"f2f48454\",\"interview_前端面试之道-闭包.md\":\"cb39a38d\",\"interview_面试-算法.md\":\"3da28c08\",\"webcomponents_2. customelements.md\":\"dfe9fc79\",\"work_ios小白条问题.md\":\"df675eb7\",\"vue3_入门.md\":\"38c4fc45\",\"webpack_重学webpack-02模块化原理.md\":\"7c97f9af\",\"vue_重学vue-02数据驱动视图.md\":\"2e4b291d\",\"jiagou_异步组件设计.md\":\"fe5e6361\",\"interview_各种题目01.md\":\"ee09148f\",\"microfrontend_架构思想.md\":\"2ee157bf\",\"vue_重学vue-10ref是什么.md\":\"c6918c48\",\"js_luhn算法.md\":\"8e92243c\",\"node_cheetah-learn.md\":\"2fb6699c\",\"jiagou_插件式设计.md\":\"009ac126\",\"vue3_前期初始化项目步骤.md\":\"399d0cf7\",\"js_前端模块化.md\":\"d4620865\",\"vue_keep-alive原理.md\":\"5faa2303\",\"interview_面试-数据结构.md\":\"dbe1bd44\"}")</script>
    <script type="module" async src="/giteepage_blog/assets/app.8c2b9bab.js"></script>
    
  </body>
</html>